Added basecamp agent

Dominik Sander преди 10 години
родител
ревизия
67bfe670bf
променени са 3 файла, в които са добавени 193 реда и са изтрити 0 реда
  1. 92 0
      app/models/agents/basecamp_agent.rb
  2. 21 0
      spec/data_fixtures/basecamp.json
  3. 80 0
      spec/models/agents/basecamp_agent_spec.rb

+ 92 - 0
app/models/agents/basecamp_agent.rb

@@ -0,0 +1,92 @@
1
+module Agents
2
+  class BasecampAgent < Agent
3
+    cannot_receive_events!
4
+
5
+    description <<-MD
6
+      The BasecampAgent checks a Basecamp project for new Events
7
+
8
+      It is required that you enter your Basecamp credentials (`username` and `password`).
9
+
10
+      You also need to provide your Basecamp `user_id` and the `project_id` of the project you want to monitor.
11
+      If you have your Basecamp project opened in your browser you can find the user_id and project_id as follows:
12
+
13
+      `https://basecamp.com/`
14
+      user_id
15
+      `/projects/`
16
+      project_id
17
+      `-explore-basecamp`
18
+    MD
19
+
20
+    event_description <<-MD
21
+      Events are the raw JSON provided by the Basecamp API. Should look something like:
22
+
23
+        {
24
+          "creator": {
25
+            "fullsize_avatar_url": "https://dge9rmgqjs8m1.cloudfront.net/global/dfsdfsdfdsf/original.gif?r=3",
26
+            "avatar_url": "http://dge9rmgqjs8m1.cloudfront.net/global/dfsdfsdfdsf/avatar.gif?r=3",
27
+            "name": "Dominik Sander",
28
+            "id": 123456
29
+          },
30
+          "attachments": [],
31
+          "raw_excerpt": "test test",
32
+          "excerpt": "test test",
33
+          "id": 6454342343,
34
+          "created_at": "2014-04-17T10:25:31.000+02:00",
35
+          "updated_at": "2014-04-17T10:25:31.000+02:00",
36
+          "summary": "commented on whaat",
37
+          "action": "commented on",
38
+          "target": "whaat",
39
+          "url": "https://basecamp.com/12456/api/v1/projects/76454545-explore-basecamp/messages/76454545-whaat.json",
40
+          "html_url": "https://basecamp.com/12456/projects/76454545-explore-basecamp/messages/76454545-whaat#comment_76454545"
41
+        }
42
+    MD
43
+
44
+    default_schedule "every_10m"
45
+
46
+    def default_options
47
+      {
48
+        'username' => '',
49
+        'password' => '',
50
+        'user_id' => '',
51
+        'project_id' => '',
52
+      }
53
+    end
54
+
55
+    def validate_options
56
+      errors.add(:base, "you need to specify your basecamp username") unless options['username'].present?
57
+      errors.add(:base, "you need to specify your basecamp password") unless options['password'].present?
58
+      errors.add(:base, "you need to specify your basecamp user id") unless options['user_id'].present?
59
+      errors.add(:base, "you need to specify the basecamp project id of which you want to receive events") unless options['project_id'].present?
60
+    end
61
+
62
+    def working?
63
+      (events_count.present? && events_count > 0)
64
+    end
65
+
66
+    def check
67
+      log "Requesting events from #{request_url}"
68
+      reponse = HTTParty.get request_url, auth_options.merge(:headers => {"User-Agent" => "Huginn (https://github.com/cantino/huginn)"})
69
+      memory[:last_run] = Time.now.utc.iso8601
70
+      if last_check_at != nil
71
+        JSON.parse(reponse.body).each do |event|
72
+          create_event :payload => event
73
+        end
74
+      end
75
+      save!
76
+    end
77
+
78
+  private
79
+    def first_run?
80
+      memory[:first_run].nil?
81
+    end
82
+
83
+    def request_url
84
+      since = memory[:last_run] ? "?since=#{memory[:last_run]}" : ''
85
+      "https://basecamp.com/#{URI.encode(options[:user_id].to_s)}/api/v1/projects/#{URI.encode(options[:project_id].to_s)}/events.json#{since}"
86
+    end
87
+
88
+    def auth_options
89
+      {:basic_auth => {:username =>options[:username], :password=>options[:password]}}
90
+    end
91
+  end
92
+end

+ 21 - 0
spec/data_fixtures/basecamp.json

@@ -0,0 +1,21 @@
1
+[
2
+  {
3
+    "creator": {
4
+      "fullsize_avatar_url": "https://dge9rmgqjs8m1.cloudfront.net/global/dfsdfsdfdsf/original.gif?r=3",
5
+      "avatar_url": "http://dge9rmgqjs8m1.cloudfront.net/global/dfsdfsdfdsf/avatar.gif?r=3",
6
+      "name": "Dominik Sander",
7
+      "id": 123456
8
+    },
9
+    "attachments": [],
10
+    "raw_excerpt": "test test",
11
+    "excerpt": "test test",
12
+    "id": 6454342343,
13
+    "created_at": "2014-04-17T10:25:31.000+02:00",
14
+    "updated_at": "2014-04-17T10:25:31.000+02:00",
15
+    "summary": "commented on whaat",
16
+    "action": "commented on",
17
+    "target": "whaat",
18
+    "url": "https://basecamp.com/12456/api/v1/projects/5476464-explore-basecamp/messages/24598238-whaat.json",
19
+    "html_url": "https://basecamp.com/12456/projects/5476464-explore-basecamp/messages/24598238-whaat#comment_150756301"
20
+  }
21
+]

+ 80 - 0
spec/models/agents/basecamp_agent_spec.rb

@@ -0,0 +1,80 @@
1
+require 'spec_helper'
2
+
3
+describe Agents::BasecampAgent do
4
+  before(:each) do
5
+    stub_request(:get, /json$/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/basecamp.json")), :status => 200, :headers => {"Content-Type" => "text/json"})
6
+    stub_request(:get, /Z$/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/basecamp.json")), :status => 200, :headers => {"Content-Type" => "text/json"})
7
+    @valid_params = {
8
+                      :username   => "user",
9
+                      :password   => "pass",
10
+                      :user_id    => 12345,
11
+                      :project_id => 6789,
12
+                    }
13
+
14
+    @checker = Agents::BasecampAgent.new(:name => "somename", :options => @valid_params)
15
+    @checker.user = users(:jane)
16
+    @checker.save!
17
+  end
18
+
19
+  describe "validating" do
20
+    before do
21
+      @checker.should be_valid
22
+    end
23
+
24
+    it "should require the basecamp username" do
25
+      @checker.options['username'] = nil
26
+      @checker.should_not be_valid
27
+    end
28
+
29
+    it "should require the basecamp password" do
30
+      @checker.options['password'] = nil
31
+      @checker.should_not be_valid
32
+    end
33
+
34
+    it "should require the basecamp user_id" do
35
+      @checker.options['user_id'] = nil
36
+      @checker.should_not be_valid
37
+    end
38
+
39
+    it "should require the basecamp project_id" do
40
+      @checker.options['project_id'] = nil
41
+      @checker.should_not be_valid
42
+    end
43
+
44
+  end
45
+
46
+  describe "helpers" do
47
+    it "should generate a correct auth hash" do
48
+      @checker.send(:auth_options).should == {:basic_auth=>{:username=>"user", :password=>"pass"}}
49
+    end
50
+
51
+    it "should not provide the since attribute on first run" do
52
+      @checker.send(:request_url).should == "https://basecamp.com/12345/api/v1/projects/6789/events.json"
53
+    end
54
+
55
+    it "should provide the since attribute after the first run" do
56
+      time = (Time.now-1.minute).iso8601
57
+      @checker.memory[:last_run] = time
58
+      @checker.save
59
+      @checker.reload.send(:request_url).should == "https://basecamp.com/12345/api/v1/projects/6789/events.json?since=#{time}"
60
+    end
61
+  end
62
+  describe "#check" do
63
+    it "should not emit events on its first run" do
64
+      expect { @checker.check }.to change { Event.count }.by(0)
65
+    end
66
+    it "should check that initial run creates an event" do
67
+      @checker.last_check_at = Time.now - 1.minute
68
+      expect { @checker.check }.to change { Event.count }.by(1)
69
+    end
70
+  end
71
+
72
+  describe "#working?" do
73
+    it "it is working when at least one event was emited" do
74
+      @checker.should_not be_working
75
+      @checker.last_check_at = Time.now - 1.minute
76
+      @checker.check
77
+      @checker.reload.should be_working
78
+    end
79
+  end
80
+end